use crate::{
    error::AppErr,
    global::APP,
    serialport::{cmd, proto::{
        address::CARGO1,
        cmd::cargo::StatusInfoDescript,
        Frame,
    }, BodyDecode},
};

pub fn exec(frame: Frame) -> Result<(), AppErr> {
    let cmd = frame.cmd();
    match cmd {
        cmd::STATUS => on_status(frame),
        _ => Err(AppErr::Static("unknown cmd")),
    }
}

struct Status {
    version: u16,
    sensor: u16,
}

impl<'de> BodyDecode<'de> for Status {
    fn decode(buf_ref: &mut &[u8]) -> Option<Self>
        where
            Self: Sized {
        let version = u16::decode(buf_ref)?;
        let sensor = u16::decode(buf_ref)?;
        Some(Status { version, sensor })
    }
}

fn on_status(frame: Frame) -> Result<(), AppErr> {
    let status: Status = frame.parse_cmd()?;
    let version = format!("{:04x}", status.version);
    let status = StatusInfoDescript::new(version, status.sensor);
    if frame.src() == CARGO1 {
        APP.notify_cargo1(&status);
    } else {
        APP.notify_cargo2(&status);
    }

    Ok(())
}
